package utils

import "sort"

func fnv32(key string) uint32 {
	const prime32 = uint32(16777619)
	hashCode := uint32(2166136261)
	for i := 0; i < len(key); i++ {
		hashCode *= prime32
		hashCode ^= uint32(key[i])
	}
	return hashCode
}

func spread(size uint32, hashCode uint32) uint32 {
	return (size - 1) & hashCode
}

func GetIndex(size int, key string) uint32 {
	return spread(uint32(size), fnv32(key))
}

func GetIndexSet(size int, keys []string) map[uint32]struct{} {
	indexSet := make(map[uint32]struct{})
	for _, key := range keys {
		index := GetIndex(size, key)
		indexSet[index] = struct{}{}
	}
	return indexSet
}

func GetIndices(size int, keys []string) []uint32 {
	indexSet := GetIndexSet(size, keys)
	indices := make([]uint32, 0, len(indexSet))
	for index := range indexSet {
		indices = append(indices, index)
	}
	sort.Slice(indices, func(i, j int) bool {
		return indices[i] < indices[j]
	})
	return indices
}
